package calendar

import (
	"log"
	"math"
	strconv2 "strconv"
	"strings"
	time2 "time"
)

//天干常量
var strHeavenlyStem = [10]string{"甲", "乙", "丙", "丁", "戊", "己", "庚", "辛", "壬", "癸"}

//地支常量
var strGroundBranch = [12]string{"子", "丑", "寅", "卯", "辰", "巳", "午", "未", "申", "酉", "戌", "亥"}

//节气常量
var fThrottleInfo = [][24]float64{{4.6295, 19.4599, 6.3826, 21.4155, 5.59, 20.888, 6.318, 21.86, 6.5, 22.2,
	7.928, 23.65, 8.35, 23.95, 8.44, 23.822, 9.098, 24.218, 8.218, 23.08, 7.9, 22.6, 6.11, 20.84}, {5.4055,
	20.12, 3.87, 18.73, 5.63, 20.646, 4.81, 20.1, 5.52, 21.04, 5.678, 21.37, 7.108, 22.83, 7.5, 23.13, 7.646,
	23.042, 8.318, 23.438, 7.438, 22.36, 7.18, 21.94}}

/**
获取天干地支
*/
func getStemBranch(iIndex int64) string {
	return strHeavenlyStem[iIndex%10] + strGroundBranch[iIndex%12]
}

/**
返回 小时对应的 支的索引
*/
func getHourBranch(iHour int) int {
	if iHour >= 23 || iHour < 1 {
		return 0
	} else if iHour >= 1 && iHour < 3 {
		return 1
	} else if iHour >= 3 && iHour < 5 {
		return 2
	} else if iHour >= 5 && iHour < 7 {
		return 3
	} else if iHour >= 7 && iHour < 9 {
		return 4
	} else if iHour >= 9 && iHour < 11 {
		return 5
	} else if iHour >= 11 && iHour < 13 {
		return 6
	} else if iHour >= 13 && iHour < 15 {
		return 7
	} else if iHour >= 15 && iHour < 17 {
		return 8
	} else if iHour >= 17 && iHour < 19 {
		return 9
	} else if iHour >= 19 && iHour < 21 {
		return 10
	} else if iHour >= 21 && iHour < 23 {
		return 11
	} else {
		return -1
	}
}

/**
根据 日干 推算 时柱 根据提供的推算图来计算
*/
func getHourStem(sStem string, iHour int) int {
	var iIndex int = -1
	for iStem, strHStem := range strHeavenlyStem {
		if strings.Compare(strHStem, sStem) == 0 {
			iIndex = iStem
		}
	}
	iIndex = iIndex % 5 // 五个为一周期
	var iHourIndex int = getHourBranch(iHour)
	var iReturn int = -1
	if iHourIndex > 10 {
		iReturn = iHourIndex - 10 + (iIndex-1)*2
	} else {
		iHourIndex = iHourIndex + (iIndex-1)*2
		if iHourIndex > 10 {
			iReturn = iHourIndex % 10
		} else {
			iReturn = iHourIndex
		}
	}
	return iReturn
}

/**
节气时间 毫秒 UTC
*/
func getThrottleDay(iYear int, iThrottle int) int64 {
	const fD float64 = 0.2422
	var iIndex int = -1
	var iYearEnd int = -1
	if (iYear >= 1900) && (iYear < 2000) {
		iIndex = 0
		iYearEnd = iYear - 1900
	} else if (iYear >= 2000) && (iYear < 2100) {
		iIndex = 1
		iYearEnd = iYear - 2000
	}
	if (iIndex == -1) || (iYearEnd == -1) {
		return -1
	}
	var iDay int = int(math.Trunc(float64(iYearEnd)*fD+fThrottleInfo[iIndex][iThrottle])) - (iYearEnd-1)/4
	var iMonth int = iThrottle/2 + 1
	var strDay = strconv2.Itoa(iYear) + "-"
	if iMonth >= 10 {
		strDay += strconv2.Itoa(iMonth) + "-"
	} else {
		strDay += "0" + strconv2.Itoa(iMonth) + "-"
	}
	if iDay >= 10 {
		strDay += strconv2.Itoa(iDay)
	} else {
		strDay += "0" + strconv2.Itoa(iDay)
	}
	strDay += " 00:00:00"
	timeThrottle, _ := time2.Parse("2006-01-02 15:04:05", strDay)
	return timeThrottle.UnixNano() / 1000 / 1000
}

/**
获取UTC时间
*/
func getUTCTime(iYear int, iMonth int, iTimeZone int64) int64 {
	var strDay = strconv2.Itoa(iYear) + "-"
	if iMonth >= 10 {
		strDay += strconv2.Itoa(iMonth) + "-"
	} else {
		strDay += "0" + strconv2.Itoa(iMonth) + "-"
	}
	strDay += "01 00:00:00"

	timeThrottle, _ := time2.Parse("2006-01-02 15:04:05", strDay)
	return timeThrottle.Unix() - iTimeZone*60*60
}

func EightCharactersOfDate(strDate string) string {
	timeThrottle, err := time2.Parse("2006-01-02 15:04:05", strDate)
	if err != nil {
		log.Fatalln(err)
		return ""
	}

	var iYear, iMonth, iDay, iHour int64 = int64(timeThrottle.Year()), int64(timeThrottle.Month()), int64(timeThrottle.Day()),
		int64(timeThrottle.Hour())
	var strYear, strMonth, strDay, strHour string

	if iMonth < 2 {
		strYear = getStemBranch(iYear - 1900 + 36 - 1)
	} else {
		strYear = getStemBranch(iYear - 1900 + 36)
	}

	var iSpringDate int64 = getThrottleDay(int(iYear), 2) // 立春日期
	// 月柱 1900年1月小寒以前为 丙子月(60进制12)
	var firstNode int64 = getThrottleDay(int(iYear), int(iMonth*2)) // 返回当月「节」为几日开始
	strMonth = getStemBranch((iYear-1900)*12 + iMonth + 12)
	//当月一日与 1900/1/1 相差天数
	//1900/1/1与 1970/1/1 相差25567日, 1900/1/1 日柱为甲戌日(60进制10)
	var dayCyclical int64 = getUTCTime(int(iYear), int(iMonth), 8)/86400 + 25567 + 10
	// 依节气调整二月分的年柱, 以立春为界
	if iMonth == 1 && int64(iDay+1) >= iSpringDate {
		strYear = getStemBranch(iYear - 1900 + 36)
	}
	// 依节气月柱, 以「节」为界
	if int64(iDay+1) >= firstNode {
		strMonth = getStemBranch((iYear-1900)*12 + iMonth + 13)
	}

	// 日柱
	strDay = getStemBranch(dayCyclical + int64(iDay))

	// 时柱
	strHour = strHeavenlyStem[getHourStem(strDay, int(iHour))] + strGroundBranch[getHourBranch(int(iHour))]
	return strYear + strMonth + strDay + strHour
}
